// Hi Emacs, this is -*- mode: csharp; -*-
///////////////////////////////////////////////////////////////////////////////////////////////////
// Serves a a test for WavFileWriter and WavFileReader classes and, at the same time, as an example
// of usage of both.
//
// Copyright (C) 2008 Javier Valcarce-Garcia, <javier.valcarce@gmail.com>
///////////////////////////////////////////////////////////////////////////////////////////////////
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Dsp;
#endregion


namespace Dsp
{
    class WavFileTester
    {
        // Sinusoid frequency and sampling rate
        const double _freq = 0.015;
        const int      _fs = 44100;

        // Input WAV files to do the test, must pre-exist with the indicated names, create them 
        // with Audacity or other software in format PCM08, PCM16, PCM24 and FLT32. You can also 
        // use Matlab's 'wavwrite' function
        const string ifile = "i_dtmf_"; // i_dtmf_PCM08.wav, i_dtmf_PCM16.wav, etc...
        const string ofile = "o_dtmf_";

        WavFileReader wavrd; // wav file reader
        WavFileWriter wavwr; // wav file writer

        // buffer to store audio samples
        double[] buf = new double[44100];

        public void Test()
        {
            // Check all possible combinations for input and output sample formats
            //
            Console.WriteLine("PCM08 -> PCM08"); Proc(WavFormat.PCM08, WavFormat.PCM08);
            Console.WriteLine("PCM08 -> PCM16"); Proc(WavFormat.PCM08, WavFormat.PCM16);
            Console.WriteLine("PCM08 -> PCM24"); Proc(WavFormat.PCM08, WavFormat.PCM24);
            Console.WriteLine("PCM08 -> FLT32"); Proc(WavFormat.PCM08, WavFormat.FLT32);
            //
            Console.WriteLine("PCM16 -> PCM08"); Proc(WavFormat.PCM16, WavFormat.PCM08);
            Console.WriteLine("PCM16 -> PCM16"); Proc(WavFormat.PCM16, WavFormat.PCM16);
            Console.WriteLine("PCM16 -> PCM24"); Proc(WavFormat.PCM16, WavFormat.PCM24);
            Console.WriteLine("PCM16 -> FLT32"); Proc(WavFormat.PCM16, WavFormat.FLT32);
            //
            Console.WriteLine("PCM24 -> PCM08"); Proc(WavFormat.PCM24, WavFormat.PCM08);
            Console.WriteLine("PCM24 -> PCM16"); Proc(WavFormat.PCM24, WavFormat.PCM16);
            Console.WriteLine("PCM24 -> PCM24"); Proc(WavFormat.PCM24, WavFormat.PCM24);
            Console.WriteLine("PCM24 -> FLT32"); Proc(WavFormat.PCM24, WavFormat.FLT32);
            //
            Console.WriteLine("FLT32 -> PCM08"); Proc(WavFormat.FLT32, WavFormat.PCM08);
            Console.WriteLine("FLT32 -> PCM16"); Proc(WavFormat.FLT32, WavFormat.PCM16);
            Console.WriteLine("FLT32 -> PCM24"); Proc(WavFormat.FLT32, WavFormat.PCM24);
            Console.WriteLine("FLT32 -> FLT32"); Proc(WavFormat.FLT32, WavFormat.FLT32);


            Console.WriteLine("Finished.");
        }


        // Reads and input WAV file, add to the input signal a sinusoid and record the output signal 
        // in a WAV file with the indicated sample format.
        private void Proc(WavFormat iformat, WavFormat oformat)
        {
            string istr = ifile + iformat.ToString() + ".wav";
            string ostr = ofile + iformat.ToString() + "_" + oformat.ToString() + ".wav";

            wavrd = new WavFileReader(istr);
            wavwr = new WavFileWriter(ostr, oformat, wavrd.Fs);

            if (!wavrd.Valid)
            {
                Console.WriteLine("Bad file format: {0}", istr);
                return;
            }

            Console.WriteLine("Adding to the input a tone of {0}Hz ...", _freq * _fs);

            int xfer;
            int n = 0;

            while (true)
            {
                xfer = wavrd.XferData(buf, 0, buf.Length);
                if (xfer == 0)
                    break;

                for (int j = 0; j < xfer; j++)
                {
                    
                    buf[j] += Math.Cos(2 * Math.PI * _freq * n) / 4;
                    n++;
                }

                wavwr.XferData(buf, 0, xfer);
            }

            wavrd.Close();
            wavwr.Close();            
        }        
    }
}
